<?php

namespace app\devices\command;

use app\devices\service\DevicesService;
use app\devices\service\SocketService;
use think\admin\Command;
use think\admin\Exception;
use think\cache\driver\Redis;
use think\console\input\Argument;
use think\console\Input;
use think\console\Output;
use think\Log;

/**
 * 发送设备模板指令
 * Class SendLockSocket
 * @package app\data\command
 */
class SendStartSocket extends Command
{
    protected $redis;

    protected function configure()
    {
        $this->setName('xdevice:SendStartSocket');
        $this->addArgument('device_id', Argument::OPTIONAL, "设备ID");
        $this->setDescription('发送获取设备板子状态指令');
        $this->redis = new Redis();
    }

    /**
     * 业务指令执行
     * @param Input $input
     * @param Output $output
     * @return void
     * @throws Exception
     */
    protected function execute(Input $input, Output $output)
    {
        $this->addThreadStart();
    }

    private function addThreadStart(){
        $time = 60;
        try {
            while ($time){
                $time = $time-1;
                while ($device_id = $this->redis->handler()->lpop("BoardStart")){
                    if($device_id){
                        $pid = pcntl_fork();
                        if ($pid == -1) {

                        } elseif ($pid) {
//                        echo "主进程：".date("Y-m-d H:i:s").",次数：".$time.PHP_EOL;
                        } else {
                            $this->redis = new Redis();
                            $appid = sysconf("wechat.appid");
                            $url = $appid=='wx7e76ad039884c1f9'?'https://jcgbackground.haoda365.cn':'http://jcgtest.haoda365.cn';
                            $url .= '/devices/api.index/flush?device_id='.$device_id;
                            dump($this->asyncPost($url, 1));
                            exit(0);
                        }
                    }
                }
                echo "_".date("Y-m-d H:i:s").PHP_EOL;
                sleep(1);
            }
        }catch (\Exception $e){
            echo $e->getMessage().PHP_EOL;
            echo $e->getLine().PHP_EOL;
            dump($e->getTraceAsString());
        }
    }

    /**
     * 发起异步请求，忽略返回值
     * @param string $url  请求url
     * @param int $blocking
     * @return array|mixed
     */
    function asyncPost(string $url, $blocking = 1)
    {
        $args = parse_url($url); //对url做下简单处理
        $host = $args['host']; //获取上报域名
        $path = $args['path'] . '?' . $args['query'];//获取上报地址
        $fp = fsockopen($host, 80, $error_code, $error_msg, 1);
        if (!$fp) {
            \think\facade\Log::error("异步发送命令失败");
            echo "异步发送命令失败";
        } else {
            stream_set_blocking($fp, $blocking);//开启了手册上说的非阻塞模式
            stream_set_timeout($fp, 1);//设置超时
            $header = "POST $path HTTP/1.1\r\n";  //注意 GET/POST请求都行 我们需要自己按照要求拼装Header http协议遵循1.1
            $header .= "content-type:application/x-www-form-urlencoded\r\n";
            $header .= "Host: $host\r\n";
            $header .= "Connection: close\r\n\r\n";//长连接关闭
            fwrite($fp, $header);

            $con = "";
            while (!feof($fp)) {
                $con .= fgets($fp, 10240);
            }

            fclose($fp);

            preg_match_all('/(?:\{)(.*)(?:\})/i', $con, $match);

            return $match[0]??[];
        }
    }
}